package com.yfbao.horizon.docker.trx;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.yfbao.horizon.docker.entity.TrxTask;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;


/**
 * 反射触发调用执行方法
 */
@Slf4j
public class TrxTaskUtil {


    public static boolean trxInvoke(TrxTask trxTask){
        String className = trxTask.getClassName();
        String methodName = trxTask.getMethod();
        try{
//            Object serviceBean = A.getBean(Class.forName(className));
            //TODO： 获取bean
            Object serviceBean = null;
            if(serviceBean == null){
                return false;
            }
            List<Method> trxTargetMethods = getTrxTargetMethod(serviceBean, trxTask);
            if(trxTargetMethods ==null || trxTargetMethods.isEmpty()){
                return false;
            }
            for (Method trxTargetMethod : trxTargetMethods) {
                if(trxTask.getParamSize() == 0 ){
                    trxTargetMethod.invoke(serviceBean,null);
                    return true;
                }
                Class<?>[] parameterTypes = trxTargetMethod.getParameterTypes();
                if(parameterTypes == null || parameterTypes.length==0){
                    trxTargetMethod.invoke(serviceBean);
                }else {
                    Object[] params = getParams(trxTask, parameterTypes);
                    if(params ==null){
                        continue;
                    }
                    trxTargetMethod.invoke(serviceBean,params);
                    return true;
                }
            }

        } catch (Throwable t) {
            log.error("method invoke error, method:"+methodName,t);
        }
        return false;
    }

    public static Object[] getParams(TrxTask trxTask,Class<?>[] parameterTypes){
        String paramData = trxTask.getParamData();
        List<String> list = JSONArray.parseArray(paramData, String.class);

        if(list.size() != parameterTypes.length){
            System.out.println("解析后参数个数不一致");
            return null;
        }
        Object[] objects = new Object[parameterTypes.length];
        try {
            for (int i = 0; i < parameterTypes.length; i++) {
                Class<?> parameterType = parameterTypes[i];
                String s = list.get(i);
                Object o = JSON.parseObject(s, parameterType);
                objects[i]=o;
            }
            return objects;
        }catch (Throwable t){
            log.warn("parse Params error");
        }
        return null;
    }

    public static List<Method> getTrxTargetMethod(Object bean,TrxTask trxTask){
        Method[] methods = bean.getClass().getMethods();
        for (Method method : methods) {
            log.info("method name:"+method.getName()+", param size:"+method.getParameterCount()+", type:"+method.getTypeParameters());
        }
        List<Method> methodList = new ArrayList<>();
        for (Method method : methods) {
            if(method.getName().equals(trxTask.getMethod()) && method.getParameterCount()==trxTask.getParamSize()){
                methodList.add(method);
            }
        }
        return methodList;
    }
}
